import requests
import json
import time
import hmac
import base64
from urllib import parse
from urllib.parse import urlencode
from datetime import datetime
from hashlib import sha256

"""
PARAMS = {
    'api_key':"xx",
    'api_secret':"xx",
    'host':'api.hbdm.com',
    'path':'/swap-api/v1/swap_account_info',
    'params':{
        'contract_code':'BTC-USD'
    }
}
response = private_restapi_huobi(**PARAMS)
json.loads(response.text.encode())


PARAMS = {
    'api_key':'xx',
    'api_secret':'xx',
    'passphrase':'xx',
    'method':'GET',
    'path':'/api/v5/account/balance',
    'params':{
        'ccy':'CNY'
    }
}
response = private_restapi_okex(**PARAMS)
json.loads(response.text.encode())


PARAMS = {
    'api_key':'xxx',
    'api_secret':'xx',
    'method':'POST',
    'host':'https://dapi.binance.com',
    'path':'/dapi/v1/order',
    'params':{
        'symbol':'LTCUSD_PERP',
        'side':'BUY',
        'type':'MARKET',
        'quantity':'10'
    }
#     'params':{
#         'dualSidePosition':False
#     }
}
response = private_restapi_binance(**PARAMS)
json.loads(response.text.encode())
"""


def private_restapi_huobi(api_key,api_secret,host,path,params):
    """
    huobi不管是查看账户或者下单等操作，看了一圈好像全是POST方法
    """
    method = 'POST'
    timestamp = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
    timestamp = parse.quote(timestamp)
    suffix = 'AccessKeyId={}&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp={}'.format(api_key, timestamp)
    payload = '{}\n{}\n{}\n{}'.format(method.upper(), host, path, suffix)
    digest = hmac.new(api_secret.encode('utf8'), payload.encode('utf8'), digestmod=sha256).digest()
    signature = base64.b64encode(digest).decode()
    signature = parse.quote(signature)
    suffix = '{}&Signature={}'.format(suffix, signature)
    url = 'https://{}{}?{}'.format(host, path, suffix)
    headers = {
        'Accept':'application/json',
        'Content-type':'application/json'
    }
    response = requests.post(url, data=json.dumps(params),headers=headers)
    data = json.loads(response.text.encode())
    return data


def private_restapi_okex(api_key, api_secret, passphrase, method, path, params):
    """
    okex的host不跟binance和huobi一样分什么币币，币本位，U本位，直接统一一个，因此host固定，不作为参数
    okex相比其他，除了api_key和api_secret,还有passphrase
    okex查看账号等操作都是GET，下单之类的操作是POST,因此私有API操作也要分GET和POST
    """
    host = 'https://www.okex.com'
    if method == 'GET' and len(params) > 0:
        plus_path = []
        keys = params.keys()
        for key in keys:
            plus_path.append(f'{key}={params[key]}')
        path = path + '?' + '&'.join(plus_path)

    url = host + path
    timestamp = datetime.utcnow().isoformat("T", "milliseconds") + 'Z'

    body = json.dumps(params) if method == 'POST' else ''
    message = str(timestamp) + str.upper(method) + path + str(body)
    mac = hmac.new(bytes(api_secret, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256').digest()
    signature = base64.b64encode(mac)

    header = {
        'Content-Type': 'application/json',
        'OK-ACCESS-KEY': api_key,
        'OK-ACCESS-SIGN': signature,
        'OK-ACCESS-TIMESTAMP': timestamp,
        'OK-ACCESS-PASSPHRASE': passphrase
    }
    response = requests.get(url, data=body, headers=header) if method == 'GET' else requests.post(url, data=body,
                                                                                                  headers=header)
    data = json.loads(response.text.encode())
    return data


def private_restapi_binance(api_key,api_secret,method,host,path,params):
    query_string = urlencode(params)
    query_string = query_string.replace('%27', '%22')
    query_string = f'{query_string}&timestamp={int(time.time() * 1000)}' if query_string else f'timestamp={int(time.time() * 1000)}'
    signature = hmac.new(api_secret.encode('utf-8'), query_string.encode('utf-8'), sha256).hexdigest()
    url = host + path + '?' + query_string + '&signature=' + signature
    session = requests.Session()
    session.headers.update({
        'Content-Type': 'application/json;charset=utf-8',
        'X-MBX-APIKEY': api_key
    })

    if method == 'GET':
        response = session.get(url)
    elif method == 'POST':
        response = session.post(url)
    elif method == 'DELETE':
        response = session.delete(url)
    else:
        response = session.get(url)
    return response